#include "stdafx.h"

#include "parser_internal.h"
#include "parser_state.h"
#include "parser_errors.h"

#include "ast_meta.h"

namespace funpl
{

namespace parser
{

/// Parses a metatype definition.
ast::metatype* parse_metatype(parser_state &state, ast::node *parent, bool implicitSemicolons)
{
	// Optional parentheses
	if (accept_cont(state, token_type::tok_oparen))
	{
		auto metatype = parse_metatype(state, parent, false);
		expect_cont(state, token_type::tok_cparen);
		return metatype;
	}
	else
	{
		auto metatype = state.tree->create_node<ast::metatype>(parent);

		// Metatype
		metatype->name = expect_cont(state, token_type::tok_identifier).token.range;

		// Restrictions
		if (accept_cont(state, token_type::tok_op_colon))
			metatype->restrictions = parse_type(state, parent, implicitSemicolons);

		return metatype;
	}
}

/// Parses a metavariable.
ast::metavariable* parse_metavariable(parser_state &state, ast::node *parent, bool implicitSemicolons)
{
	expect_cont(state, token_type::kw_def);

	auto variable = state.tree->create_node<ast::metavariable>(parent);

	// Name
	variable->name = expect_cont(state, token_type::tok_identifier).token.range;

	// Type
	if (accept_cont(state, token_type::tok_op_colon))
		variable->type = parse_type(state, variable, implicitSemicolons);

	// Default
	if (accept_cont(state, token_type::op_assign))
		variable->defaultValue = parse_expression(state, variable, implicitSemicolons);

	return variable;
}

} // namespace

} // namespace